#
# This file is part of TeamTools.
#
# TeamTools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License V2 as published by
# the Free Software Foundation.
#
# TeamTools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License V2 for more details.
#
# You should have received a copy of the GNU General Public License
# along with TeamTools (see the LICENSE file)
#
# Copyright (2009 - 2014) - Mark Leeuw
#


package SVN::TeamTools::Plugins::MergeEnv;

use warnings;
use strict;
use Carp;
use Error qw(:try);

use SVN::TeamTools::Store::Config;
use SVN::TeamTools::Store::Repo;

use HTML::Template;
use CGI;
use URI::Escape;
use Data::Dumper;

use DBI;

my $conf;
my $logger;
BEGIN { $conf = SVN::TeamTools::Store::Config->new(); $logger = $conf->{logger}; }

sub hasAction {
	shift;
	my %args	= @_;
	my $action	= $args{action};
	return ("|dsp.merge-env|get.merge-env.matrix|set.merge-env|get.env-branches|" =~ /\|\Q$action\E\|/);
}

sub getTemplate {
	shift;
	my %args	= @_;
	my $action	= $args{action};
	my $cgi		= $args{cgi};

	my $template = HTML::Template->new( filename => 'SVN/TeamTools/Plugins/tmpl/merge-env.tmpl', path => @INC );

	return $template;
}

sub getData {
	shift;
	my %args	= @_;
	my $action	= $args{action};
	my $param	= $args{param};

	my $mergeenv	= SVN::TeamTools::Plugins::MergeEnv->new();
	my %result;

	if ($action =~ /get.merge-env.matrix/) {

		my %envs;
		my %branches;
		my %checked;
		my $sth;


		try {
			$sth = $mergeenv->{dbh}->prepare("SELECT id, name FROM environments ORDER BY id");
			$sth->execute() or die "Failing to execute statement";
			while (my ($id,$name) = $sth->fetchrow()) {
				$envs{$id} = $name;
			}

			$sth = $mergeenv->{dbh}->prepare("SELECT id, name FROM branches ORDER BY id");
			$sth->execute() or die "Failing to execute statement";
			while (my ($id,$name) = $sth->fetchrow()) {
				$branches{$id} = $name;
			}

			$sth = $mergeenv->{dbh}->prepare("SELECT environment, branch, status FROM merge_env");
			$sth->execute() or die "Failing to execute statement";
			while (my ($env, $brn, $status) = $sth->fetchrow()) {
				$checked{$env . ',' . $brn}=$status
			}
		} otherwise {
			my $exc = shift; 
			$logger->error ($exc);
			croak "Error fetching data,  error: $exc";
		};


		%result = (
			envs		=> \%envs,
			branches	=> \%branches,
			checked		=> \%checked
		);
	} elsif ($action =~ /set.merge-env/) {
		foreach my $act (@{$param->{cactions}}) {
			my $stmnt;
			my @c = split(',',$act->{box});
			if ($act->{value} eq 'C') {
				$stmnt="INSERT INTO merge_env VALUES ($c[0] ,$c[1] ,'B')";
			}
			if ($act->{value} eq 'U') {
				$stmnt='DELETE FROM merge_env WHERE environment=' . $c[0] . ' AND branch=' . $c[1];
			}
			try {
				$logger->debug ($stmnt);
				$mergeenv->{dbh}->do($stmnt);
			} otherwise {
				my $exc = shift;
				croak "Error executing $stmnt,  error: $exc";
			};
			
		}
	} elsif ($action =~ /get.env-branches/) {
		my @branches;
		try {
			my $stmnt = "SELECT b.name FROM branches b, merge_env m, environments e WHERE e.name='" . $param->{environment}. "' AND e.id = m.environment AND m.status='B' AND m.branch=b.id";
			$logger->debug ($stmnt);

			my $sth = $mergeenv->{dbh}->prepare($stmnt);
			$sth->execute() or die "Failing to execute statement";
			while (my ($name) = $sth->fetchrow()) {
				push (@branches,$name);
			}
		} otherwise {
			my $exc = shift;
			croak "Error executing SQL statement,  error: $exc";
		};
		%result = (
			environment	=> $param->{environment},
			branches	=> \@branches
		);
	}
	return \%result;
}

sub calcBranches {
	my $mergeenv	= SVN::TeamTools::Plugins::MergeEnv->new();
	my $branch_regex = $conf->{config}->{svn}->{regex_branch};

	$branch_regex =~ s/^\///g;

	my @depth = split('/',$branch_regex);

	my @branches = @{SVN::TeamTools::Store::Repo->calcDynContext(regex=>$conf->{config}->{svn}->{regex_branch} . "[^/]+", depth=>scalar(@depth))};

	my %dbbranches;
	my $sth;
	my $stmnt;
	try {
		$sth = $mergeenv->{dbh}->prepare("SELECT id, name FROM branches ORDER BY id");
		$sth->execute() or die "Failing to execute statement";
		while (my ($id,$name) = $sth->fetchrow()) {
			$dbbranches{$name} = $id;
		}
	} otherwise {
		my $exc = shift;
		croak "Error executing $stmnt,  error: $exc";
	};

## See if there are any new branches. If a branch exists in the DB already, remove it from the hash (so only delete branches remain in the hash)
	foreach my $branch (@branches) {
		if (! exists $dbbranches{$branch}) {
			try {
				$mergeenv->{dbh}->do("INSERT INTO branches (name) VALUES ('$branch')");
			} otherwise {
				my $exc = shift;
				croak "Error executing $stmnt,  error: $exc";
			};
		} else {
			delete $dbbranches{$branch};
		}
	}

# Delete remainig branches in the hash from the database
	foreach my $branch (keys %dbbranches) {
		try {
			$mergeenv->{dbh}->do("DELETE FROM merge_env WHERE branch = " . $dbbranches{$branch});
			$mergeenv->{dbh}->do("DELETE FROM branches WHERE id = " . $dbbranches{$branch});
		} otherwise {
			my $exc = shift;
			croak "Error executing $stmnt,  error: $exc";
		};
	}
}

# Constructor
sub new {
	my $class	= shift;
	my %args	= @_;
	my $create	= $args{create};

	my $self = {};
	try {
		$self = {
#			dbh => DBI->connect("dbi:SQLite:dbname=" . $conf->{config}->{mailer}->{maildb},"",""),
			dbh => DBI->connect("dbi:SQLite:dbname=/var/db/sqlite/merge-env01.sqlite","",""),
		};
	} otherwise {
		my $exc = shift;
		croak "Error opening database with path /var/db/sqlite/merge-env01.sqlite error: $exc";
	};
       if ($create) {
		try {
			$self->{dbh}->do("DROP TABLE IF EXISTS environments");
			$self->{dbh}->do("CREATE TABLE environments (id INTEGER PRIMARY KEY, name TEXT)");
#			$self->{dbh}->do("CREATE UNIQUE INDEX _idx1 ON mailusers(username)");
 
			$self->{dbh}->do("DROP TABLE IF EXISTS branches");
			# Targettype can be Path or Message
			$self->{dbh}->do("CREATE TABLE branches (id INTEGER PRIMARY KEY, name TEXT)");
#			$self->{dbh}->do("CREATE INDEX mailrules_idx1 ON mailrules(username)");
#
			$self->{dbh}->do("DROP TABLE IF EXISTS merge_env");
			# Targettype can be Path or Message
			$self->{dbh}->do("CREATE TABLE merge_env (environment INTEGER, branch INTEGER, status TEXT)");
#			$self->{dbh}->do("CREATE INDEX mailrules_idx1 ON mailrules(username)");
		} otherwise {
			my $exc = shift;
			croak "Error creating tables structure,  error: $exc";
		};
	}
	bless $self, $class;
	return $self;
}
1;
